/*
 * Copyright (C) 2008 Esmertec AG.
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sqlcipher.database;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.data.dataability.DataAbilityPredicates;
import ohos.data.rdb.ValuesBucket;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import ohos.data.resultset.ResultSet;
import ohos.utils.net.Uri;
import ohos.agp.window.dialog.ToastDialog;

/**
 * @hide
 */

public final class SqliteWrapper {
    private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00206, "SqliteWrapper");
    private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
        = "unable to open database file";

    private SqliteWrapper() {
        // Forbidden being instantiated.
    }

    // FIXME: need to optimize this method.
    private static boolean isLowMemory(SQLiteException e) {
        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
    }

    public static void checkSQLiteException(Context context, SQLiteException e) {
        if (isLowMemory(e)) {
            ToastDialog toast = new ToastDialog(context);
            toast.setText(e.getMessage()).show();
        } else {
            throw e;
        }
    }

    public static ResultSet query(Context context, DataAbilityHelper resolver, Uri uri,
                                  String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        try {
            DataAbilityPredicates predicates = createPredicateFromSelection(selection, selectionArgs);
            predicates.setOrder(sortOrder);
            return (ResultSet) resolver.query(uri, projection, predicates);
        } catch (SQLiteException e) {
            HiLog.error(label, "Catch a SQLiteException when query: ", e);
            checkSQLiteException(context, e);
            return null;
        } catch (DataAbilityRemoteException e) {
            HiLog.error(label, "Catch a SQLiteException when query: ", e);
            return null;
        }
    }

    private static DataAbilityPredicates createPredicateFromSelection(String selection, String[] selectionArgs) {
        DataAbilityPredicates predicates = new DataAbilityPredicates(selection);
        List<String> args = new ArrayList<>(Arrays.asList(selectionArgs));
        predicates.setWhereArgs(args);
        return predicates;
    }

/*    public static boolean requery(Context context, ResultSet cursor) { //deprecated method, removed
        try {
            return cursor.requery();
        } catch (SQLiteException e) {
            HiLog.error(label, "Catch a SQLiteException when requery: ", e);
            checkSQLiteException(context, e);
            return false;
        }
    }*/

    public static int update(Context context, DataAbilityHelper resolver, Uri uri,
                             ValuesBucket values, String where, String[] selectionArgs) {
        try {
            DataAbilityPredicates predicates = createPredicateFromSelection(where,selectionArgs);
            return resolver.update(uri, values, predicates);
        } catch (SQLiteException e) {
            HiLog.error(label, "Catch a SQLiteException when update: ", e);
            checkSQLiteException(context, e);
            return -1;
        } catch (DataAbilityRemoteException e) {
            HiLog.error(label, "Catch a SQLiteException when query: ", e);
            return -1;
        }
    }

    public static int delete(Context context, DataAbilityHelper resolver, Uri uri,
                             String where, String[] selectionArgs) {
        try {
            DataAbilityPredicates predicates = createPredicateFromSelection(where,selectionArgs);
            return resolver.delete(uri, predicates);
        } catch (SQLiteException e) {
            HiLog.error(label, "Catch a SQLiteException when delete: ", e);
            checkSQLiteException(context, e);
            return -1;
        }catch (DataAbilityRemoteException e) {
            HiLog.error(label, "Catch a SQLiteException when query: ", e);
            return -1;
        }
    }

    public static int insert(Context context, DataAbilityHelper resolver,
                             Uri uri, ValuesBucket values) {
        try {
            return resolver.insert(uri, values);
        } catch (DataAbilityRemoteException d) {
            HiLog.error(label, "Catch a DataAbilityRemoteException when insert: ", d);
            return -1;
        } catch (SQLiteException e) {
            HiLog.error(label, "Catch a SQLiteException when insert: ", e);
            checkSQLiteException(context, e);
            return -1;
        }
    }
}
